#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct cm_stack
{
	int capacity;
	int size;
	char *stack;
	char *end;
	char *pos;
};

/*
 * @brief	create a stack
 * @param	size: each element's size in this stack
 * @param	capacity: max capacity(count of elements)
 * @return	NULL for failed
 */
struct cm_stack * cm_stack_create(int size, int capacity)
{
	int len = sizeof(struct cm_stack) + capacity * size;

	struct cm_stack * stack = (struct cm_stack *) calloc(1, len);
	if (stack == NULL)
		return NULL;

	stack->capacity = capacity;
	stack->size = size;
	stack->stack = (char *) (stack + 1);
	stack->end = (stack->stack + size * capacity);
	stack->pos = stack->end;

	//printf("create: start = %p, end = %p, pos = %p\n", stack->stack,
	//		stack->end, stack->pos);

	return stack;
}

void cm_stack_delete(struct cm_stack **s)
{
	free(*s);
	*s = NULL;
}

int cm_stack_pop(struct cm_stack *s, char *data)
{
	if (s->pos < s->end) {
		memcpy(data, s->pos, s->size);
		s->pos += s->size;

		//printf("pop: start = %p, end = %p, pos = %p\n", s->stack,
		//		s->end, s->pos);

		return 0;
	} else {
		return -1;
	}
}

int cm_stack_push(struct cm_stack *s, char *data)
{
	if (s->pos > s->stack) {
		s->pos -= s->size;
		memcpy(s->pos, data, s->size);

		//printf("push: start = %p, end = %p, pos = %p\n", s->stack,
		//		s->end, s->pos);

		return 0;
	} else {
		return -1;
	}
}

inline int cm_stack_empty(struct cm_stack *s)
{
	return (s->pos == s->end);
}
